﻿// Copyright (c) 2012 Francis Xavier Joseph Pulikotil
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

using System.Collections.Generic;
using System.Text;

namespace Daabli
{
    public struct CursorPosition
    {
        public int Line { get; set; }
        public int Column { get; set; }

        public CursorPosition(int line, int column)
            : this()
        {
            Line = line;
            Column = column;
        }
    }

    public enum MessageType
    {
        Error = 1,
        Warning = 2,
        Information = 4,
        InternalError = 8,
        InvalidArgument = 16,

        // Note: Any additional message types added above this line must also be updated below.
        All = 0
        | Error
        | Warning
        | Information
        | InternalError
        | InvalidArgument
    }

    public class Message
    {
        public CursorPosition Position { get; set; }
        public MessageType Type { get; private set; }
        public string Content { get; private set; }

        public Message(CursorPosition position, MessageType type, string content)
        {
            Position = position;
            Type = type;
            Content = content ?? string.Empty;
        }

        public override string ToString()
        {
            return string.Format("[Ln {0}, Col {1}] {2}: {3}", Position.Line, Position.Column, Type, Content);
        }
    }

    public class MessageLog
    {
        // Members
        private readonly List<Message> _messages = new List<Message>();
        private CursorPosition _position = new CursorPosition(0, 0);

        // Functions
        public void SetPosition(CursorPosition position)
        {
            SetPosition(position.Line, position.Column);
        }
        public void SetPosition(int line, int column)
        {
            _position.Line = line;
            _position.Column = column;
        }

        public void Write(MessageType type, string format, params object[] args)
        {
            _messages.Add(new Message(_position, type, string.Format(format, args)));
        }
        public void Clear()
        {
            _messages.Clear();
        }

        public override string ToString()
        {
            return ToString(MessageType.All);
        }
        public string ToString(MessageType types)
        {
            var result = new StringBuilder();
            foreach (var msg in _messages)
            {
                if ((msg.Type & types) == 0)
                    continue;

                result.AppendLine(msg.ToString());
            }

            return result.ToString();
        }
    }
}
